/*
 * jxUtils Project (2014)
 * 
 * by Denilson Edinaldo Pinto
 * 
 * LGPL
 * Copyright (C) 2014
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.jxUtils.file;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.jxUtils.check.ParameterCheck;
import org.jxUtils.i18n.I18N;

/**
 * @author Denilson Edinaldo Pinto
 * @porject jxUtils
 * @package org.jxUtils.file
 * @date 19/08/2014 - 18:39:21
 */
public class MediaFile implements Serializable {
	
	private static final long serialVersionUID = 6642194196805709247L;
	
	@SuppressWarnings("unused")
	private final String name = null;
	
	@SuppressWarnings("unused")
	private final FileSize size = null;
	
	@SuppressWarnings("unused")
	private final Date lastModification = null;
	
	@SuppressWarnings("unused")
	private final String directory = null;
	
	@SuppressWarnings("unused")
	private final boolean canRead = false;
	
	@SuppressWarnings("unused")
	private final boolean canWrite = false;
	
	@SuppressWarnings("unused")
	private final boolean canExecute = false;
	
	private JXFile jxFile = null;
	
	/**
	 * 
	 */
	public MediaFile() {
	
	}
	
	/**
	 * @param file
	 */
	public MediaFile(final File file) {
	
		ParameterCheck.isNull(file, "file");
		
		setFile(new JXFile(file));
	}
	
	/**
	 * @return the canExecute
	 */
	public final boolean getCanExecute() {
	
		return getFile().canRead();
	}
	
	/**
	 * @return the canRead
	 */
	public final boolean getCanRead() {
	
		return getFile().canRead();
	}
	
	/**
	 * @return the canWrite
	 */
	public final boolean getCanWrite() {
	
		return getFile().canWrite();
	}
	
	/**
	 * @return the directory
	 */
	public final String getDirectory() {
	
		return getFile().getParent();
	}
	
	/**
	 * @return the file
	 */
	public final JXFile getFile() {
	
		return jxFile;
	}
	
	/**
	 * @return the lastModification
	 */
	public final Date getLastModification() {
	
		return getFile().getLastModified();
	}
	
	/**
	 * @return the name
	 */
	public final String getName() {
	
		return getFile().getName();
	}
	
	/**
	 * @return the size
	 */
	public final FileSize getSize() {
	
		return getFile().getSize();
	}
	
	/**
	 * @param newDirectory
	 * @throws IOException
	 */
	public final boolean moveTo(final File newDirectory) throws IOException {
	
		return getFile().moveTo(newDirectory);
	}
	
	/**
	 * @param newName
	 */
	public final boolean renameTo(final String newName) {
	
		return getFile().renameTo(newName);
	}
	
	/**
	 * @param canExecute
	 *        the canExecute to set
	 */
	public final void setCanExecute(final boolean canExecute) {
	
		getFile().setExecutable(canExecute);
	}
	
	/**
	 * @param canRead
	 *        the canRead to set
	 */
	public final void setCanRead(final boolean canRead) {
	
		getFile().setReadable(canRead);
	}
	
	/**
	 * @param canWrite
	 *        the canWrite to set
	 */
	public final void setCanWrite(final boolean canWrite) {
	
		getFile().setWritable(canWrite);
	}
	
	/**
	 * @param directory
	 *        the directory to set
	 * @throws IOException
	 */
	public final void setDirectory(final String directory) throws IOException {
	
		ParameterCheck.isNullOrAbsoluteEmpty(directory, "directory");
		
		moveTo(new File(directory));
	}
	
	/**
	 * @param jxFile
	 *        the jxFile to set
	 */
	public final void setFile(final JXFile jxFile) {
	
		this.jxFile = jxFile;
	}
	
	/**
	 * @param lastModification
	 *        the lastModification to set
	 */
	public final void setLastModification(final Date lastModification) {
	
		getFile().setLastModified(lastModification.getTime());
	}
	
	/**
	 * @param name
	 *        the name to set
	 */
	public final void setName(final String name) {
	
		renameTo(name);
	}
	
	/**
	 * @param size
	 *        the size to set
	 */
	public final void setSize(final FileSize size) {
	
		System.out.println("setSize(FileSize) NotImplementedException");
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
	
		final int prime = 31;
		int result = 1;
		result = prime * result + (getCanExecute() ? 1231 : 1237);
		result = prime * result + (getCanRead() ? 1231 : 1237);
		result = prime * result + (getCanWrite() ? 1231 : 1237);
		result = prime * result + (getDirectory() == null ? 0 : getDirectory().hashCode());
		result = prime * result + (getFile() == null ? 0 : getFile().hashCode());
		result = prime * result + (getLastModification() == null ? 0 : getLastModification().hashCode());
		result = prime * result + (getName() == null ? 0 : getName().hashCode());
		result = prime * result + (getSize() == null ? 0 : getSize().hashCode());
		return result;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(final Object obj) {
	
		if(this == obj) {
			return true;
		}
		if(obj == null) {
			return false;
		}
		if( !(obj instanceof MediaFile)) {
			return false;
		}
		final MediaFile other = (MediaFile)obj;
		if(getCanExecute() != other.getCanExecute()) {
			return false;
		}
		if(getCanRead() != other.getCanRead()) {
			return false;
		}
		if(getCanWrite() != other.getCanWrite()) {
			return false;
		}
		if(getDirectory() == null) {
			if(other.getDirectory() != null) {
				return false;
			}
		}else if( !getDirectory().equals(other.getDirectory())) {
			return false;
		}
		if(getFile() == null) {
			if(other.getFile() != null) {
				return false;
			}
		}else if( !getFile().equals(other.getFile())) {
			return false;
		}
		if(getLastModification() == null) {
			if(other.getLastModification() != null) {
				return false;
			}
		}else if( !getLastModification().equals(other.getLastModification())) {
			return false;
		}
		if(getName() == null) {
			//
			if(other.getName() != null) {
				return false;
			}
		}else if( !getName().equals(other.getName())) {
			return false;
		}
		if(getSize() == null) {
			if(other.getSize() != null) {
				return false;
			}
		}else if( !getSize().equals(other.getSize())) {
			return false;
		}
		return true;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
	
		return I18N.file().fileName() + ": " + getName() + "\n" + I18N.file().fileDirectory() + ": " + getDirectory() + "\n" + I18N.file().fileSize() + ": " + getSize() + "\n" + I18N.file().fileLastModified() + ": " + getLastModification();
	}
	
	/**
	 * @param files
	 * @return List < {@link MediaFile} >
	 */
	public static final List<MediaFile> toList(final List<File> files) {
	
		final List<MediaFile> mediaList = new ArrayList<>();
		
		synchronized(files) {
			
			//
			for(final File file : files) {
				
				mediaList.add(new MediaFile(file));
			}
		}
		
		return mediaList;
	}
}
